package cn.admin.remoting.impl;

import cn.admin.remoting.TRConstants;

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;

public class ConnectionResponse implements RemotingMessage {

    private ResponseContext ctx = new ResponseContext();
    private String host;
    private int result = 0;
    private String errorMsg;
    private String errorStack;
    private transient Object errorCause;
    private transient Object appResponse;

    public ResponseContext getCtx() {
        return ctx;
    }

    public void setCtx(ResponseContext ctx) {
        this.ctx = ctx;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public String getErrorStack() {
        return errorStack;
    }

    public void setErrorStack(String errorStack) {
        this.result = 1;
        this.errorStack = "[Server Error Stack]: " + errorStack;
    }

    public Object getErrorCause() {
        return errorCause;
    }

    public void setErrorCause(Object errorCause) {
        this.errorCause = errorCause;
    }

    public Object getAppResponse() {
        return appResponse;
    }

    public void setAppResponse(Object appResponse) {
        this.appResponse = appResponse;
    }

    public void setThrowable(Throwable t) {
        this.setErrorCause(t.toString());
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        t.printStackTrace(writer);
        writer.flush();
        this.setErrorStack(stringWriter.toString());
        writer.close();
    }

    public byte getDirection() {
        return ctx.direction;
    }

    public void setDirection(byte direction) {
        this.ctx.direction = direction;
    }

    public long getRequestId() {
        return this.ctx.id;
    }

    public void setRequestId(long requestId) {
        this.ctx.id = requestId;
    }

    @Override
    public long getMessageId() {
        return this.ctx.id;
    }

    @Override
    public byte getSerializeProtocol() {
        return this.ctx.serializeProtocol;
    }

    public void setSerializeProtocol(byte serializeType) {
        this.ctx.serializeProtocol = serializeType;
    }

    @Override
    public String toString() {
        return "ConnectionResponse[" +
                "requestId=" + this.ctx.id +
                ", result=" + TRConstants.getResultCodeMsg(this.result) +
                ", errorMsg=" + this.errorMsg +
                ", appResponse=" + this.appResponse +
                "]";
    }

    public static ConnectionResponse getResponse(ConnectionRequest request) {
        ConnectionResponse resp = new ConnectionResponse();
        resp.setRequestId(request.getId());
        resp.setDirection(request.getDirection());
        resp.setSerializeProtocol(request.getSerializeProtocol());
        return resp;
    }

    private class ResponseContext implements Serializable {

        private long id;
        private transient byte serializeProtocol;
        private transient byte direction;

        private ResponseContext() {
            this.direction = 2;
        }
    }
}
